using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using JGSY.CMS.LowCode.Platform.Application.Interfaces;
using JGSY.CMS.LowCode.Platform.Domain.Entities;
using System.ComponentModel.DataAnnotations;

namespace JGSY.CMS.LowCode.Platform.Controllers
{
    /// <summary>
    /// 通知管理API控制器
    /// 提供通知发送、模板管理、配置管理等功能
    /// </summary>
    [ApiController]
    [Route("api/[controller]")]
    [Authorize]
    public class NotificationController : ControllerBase
    {
        private readonly INotificationService _notificationService;
        private readonly ILogger<NotificationController> _logger;

        public NotificationController(
            INotificationService notificationService,
            ILogger<NotificationController> logger)
        {
            _notificationService = notificationService;
            _logger = logger;
        }

        // =============================
        // 通知发送API
        // =============================

        /// <summary>
        /// 发送通知
        /// </summary>
        [HttpPost("send")]
        public async Task<ActionResult<NotificationRecord>> SendNotification([FromBody] SendNotificationRequest request)
        {
            try
            {
                var tenantId = GetCurrentTenantId();
                var record = await _notificationService.SendNotificationAsync(
                    tenantId, 
                    request.NotificationType, 
                    request.Recipient, 
                    request.Subject ?? string.Empty, 
                    request.Content, 
                    request.Metadata);

                return Ok(record);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error sending notification");
                return StatusCode(500, new { message = "发送通知失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 使用模板发送通知
        /// </summary>
        [HttpPost("send-template")]
        public async Task<ActionResult<NotificationRecord>> SendTemplateNotification([FromBody] SendTemplateNotificationRequest request)
        {
            try
            {
                var tenantId = GetCurrentTenantId();
                var record = await _notificationService.SendTemplateNotificationAsync(
                    tenantId, 
                    request.TemplateCode, 
                    request.Recipient, 
                    request.Variables, 
                    request.Metadata);

                return Ok(record);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error sending template notification");
                return StatusCode(500, new { message = "发送模板通知失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 批量发送通知
        /// </summary>
        [HttpPost("send-batch")]
        public async Task<ActionResult<List<NotificationRecord>>> SendBatchNotification([FromBody] SendBatchNotificationRequest request)
        {
            try
            {
                var tenantId = GetCurrentTenantId();
                var records = await _notificationService.SendBatchNotificationAsync(
                    tenantId, 
                    request.TemplateCode, 
                    request.Recipients, 
                    request.Variables);

                return Ok(records);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error sending batch notification");
                return StatusCode(500, new { message = "批量发送通知失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 计划发送通知
        /// </summary>
        [HttpPost("schedule")]
        public async Task<ActionResult<NotificationRecord>> ScheduleNotification([FromBody] ScheduleNotificationRequest request)
        {
            try
            {
                var tenantId = GetCurrentTenantId();
                var record = await _notificationService.ScheduleNotificationAsync(
                    tenantId, 
                    request.TemplateCode, 
                    request.Recipient, 
                    request.Variables, 
                    request.ScheduledAt);

                return Ok(record);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error scheduling notification");
                return StatusCode(500, new { message = "计划发送通知失败", error = ex.Message });
            }
        }

        // =============================
        // 模板管理API
        // =============================

        /// <summary>
        /// 创建通知模板
        /// </summary>
        [HttpPost("templates")]
        public async Task<ActionResult<NotificationTemplate>> CreateTemplate([FromBody] CreateTemplateRequest request)
        {
            try
            {
                var tenantId = GetCurrentTenantId();
                var template = await _notificationService.CreateTemplateAsync(
                    tenantId, 
                    request.Name, 
                    request.Code, 
                    request.NotificationType, 
                    request.Subject ?? string.Empty, 
                    request.Content, 
                    request.Variables);

                return CreatedAtAction(nameof(GetTemplate), new { code = template.Code }, template);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error creating notification template");
                return StatusCode(500, new { message = "创建通知模板失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取通知模板
        /// </summary>
        [HttpGet("templates/{code}")]
        public async Task<ActionResult<NotificationTemplate>> GetTemplate(string code)
        {
            try
            {
                var tenantId = GetCurrentTenantId();
                var template = await _notificationService.GetTemplateAsync(tenantId, code);
                
                if (template == null)
                    return NotFound(new { message = "模板不存在" });

                return Ok(template);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting notification template {Code}", code);
                return StatusCode(500, new { message = "获取通知模板失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取通知模板列表
        /// </summary>
        [HttpGet("templates")]
        public async Task<ActionResult<List<NotificationTemplate>>> GetTemplates([FromQuery] string? notificationType = null, [FromQuery] bool? isEnabled = null)
        {
            try
            {
                var tenantId = GetCurrentTenantId();
                var templates = await _notificationService.GetTemplatesAsync(tenantId, notificationType, isEnabled);
                return Ok(templates);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting notification templates");
                return StatusCode(500, new { message = "获取通知模板列表失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 更新通知模板
        /// </summary>
        [HttpPut("templates/{templateId:long}")]
        public async Task<ActionResult<NotificationTemplate>> UpdateTemplate(long templateId, [FromBody] UpdateTemplateRequest request)
        {
            try
            {
                var template = await _notificationService.UpdateTemplateAsync(
                    templateId, 
                    request.Name, 
                    request.Subject, 
                    request.Content, 
                    request.Variables);

                if (template == null)
                    return NotFound(new { message = "模板不存在" });

                return Ok(template);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error updating notification template {TemplateId}", templateId);
                return StatusCode(500, new { message = "更新通知模板失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 删除通知模板
        /// </summary>
        [HttpDelete("templates/{templateId:long}")]
        public async Task<ActionResult> DeleteTemplate(long templateId)
        {
            try
            {
                var success = await _notificationService.DeleteTemplateAsync(templateId);
                
                if (!success)
                    return NotFound(new { message = "模板不存在" });

                return NoContent();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error deleting notification template {TemplateId}", templateId);
                return StatusCode(500, new { message = "删除通知模板失败", error = ex.Message });
            }
        }

        // =============================
        // 配置管理API
        // =============================

        /// <summary>
        /// 创建通知配置
        /// </summary>
        [HttpPost("configs")]
        public async Task<ActionResult<TenantNotificationConfig>> CreateConfig([FromBody] CreateConfigRequest request)
        {
            try
            {
                var tenantId = GetCurrentTenantId();
                var config = await _notificationService.CreateConfigAsync(
                    tenantId, 
                    request.NotificationType, 
                    request.Channel, 
                    request.Configuration);

                return CreatedAtAction(nameof(GetConfigs), new { notificationType = config.NotificationType }, config);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error creating notification config");
                return StatusCode(500, new { message = "创建通知配置失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取通知配置列表
        /// </summary>
        [HttpGet("configs")]
        public async Task<ActionResult<List<TenantNotificationConfig>>> GetConfigs([FromQuery] string? notificationType = null)
        {
            try
            {
                var tenantId = GetCurrentTenantId();
                var configs = await _notificationService.GetConfigsAsync(tenantId, notificationType);
                return Ok(configs);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting notification configs");
                return StatusCode(500, new { message = "获取通知配置失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 更新通知配置
        /// </summary>
        [HttpPut("configs/{configId:long}")]
        public async Task<ActionResult<TenantNotificationConfig>> UpdateConfig(long configId, [FromBody] UpdateConfigRequest request)
        {
            try
            {
                var config = await _notificationService.UpdateConfigAsync(
                    configId, 
                    request.IsEnabled, 
                    request.Configuration);

                if (config == null)
                    return NotFound(new { message = "配置不存在" });

                return Ok(config);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error updating notification config {ConfigId}", configId);
                return StatusCode(500, new { message = "更新通知配置失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 删除通知配置
        /// </summary>
        [HttpDelete("configs/{configId:long}")]
        public async Task<ActionResult> DeleteConfig(long configId)
        {
            try
            {
                var success = await _notificationService.DeleteConfigAsync(configId);
                
                if (!success)
                    return NotFound(new { message = "配置不存在" });

                return NoContent();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error deleting notification config {ConfigId}", configId);
                return StatusCode(500, new { message = "删除通知配置失败", error = ex.Message });
            }
        }

        // =============================
        // 记录查询API
        // =============================

        /// <summary>
        /// 获取通知记录
        /// </summary>
        [HttpGet("records")]
        public async Task<ActionResult<List<NotificationRecord>>> GetNotificationRecords(
            [FromQuery] string? status = null,
            [FromQuery] DateTime? startDate = null,
            [FromQuery] DateTime? endDate = null,
            [FromQuery] int page = 1,
            [FromQuery] int pageSize = 20)
        {
            try
            {
                var tenantId = GetCurrentTenantId();
                var records = await _notificationService.GetNotificationRecordsAsync(tenantId, status, startDate, endDate, page, pageSize);
                return Ok(records);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting notification records");
                return StatusCode(500, new { message = "获取通知记录失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取通知统计
        /// </summary>
        [HttpGet("statistics")]
        public async Task<ActionResult<Dictionary<string, long>>> GetNotificationStatistics(
            [FromQuery] DateTime? startDate = null,
            [FromQuery] DateTime? endDate = null)
        {
            try
            {
                var tenantId = GetCurrentTenantId();
                var statistics = await _notificationService.GetNotificationStatisticsAsync(tenantId, startDate, endDate);
                return Ok(statistics);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error getting notification statistics");
                return StatusCode(500, new { message = "获取通知统计失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 重试失败的通知
        /// </summary>
        [HttpPost("records/{recordId:long}/retry")]
        public async Task<ActionResult> RetryNotification(long recordId)
        {
            try
            {
                var success = await _notificationService.RetryNotificationAsync(recordId);
                
                if (!success)
                    return NotFound(new { message = "通知记录不存在或无法重试" });

                return Ok(new { message = "通知已加入重试队列" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error retrying notification {RecordId}", recordId);
                return StatusCode(500, new { message = "重试通知失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 取消计划的通知
        /// </summary>
        [HttpPost("records/{recordId:long}/cancel")]
        public async Task<ActionResult> CancelScheduledNotification(long recordId)
        {
            try
            {
                var success = await _notificationService.CancelScheduledNotificationAsync(recordId);
                
                if (!success)
                    return NotFound(new { message = "通知记录不存在或无法取消" });

                return Ok(new { message = "计划通知已取消" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error cancelling scheduled notification {RecordId}", recordId);
                return StatusCode(500, new { message = "取消计划通知失败", error = ex.Message });
            }
        }

        // =============================
        // 私有辅助方法
        // =============================

        private string GetCurrentTenantId()
        {
            // 从JWT令牌或请求头中获取租户ID
            return User.FindFirst("tenant_id")?.Value ?? "default";
        }
    }

    // =============================
    // 请求DTO类型
    // =============================

    public class SendNotificationRequest
    {
        [Required]
        public string NotificationType { get; set; } = string.Empty;

        [Required]
        public string Recipient { get; set; } = string.Empty;

        public string? Subject { get; set; }

        [Required]
        public string Content { get; set; } = string.Empty;

        public Dictionary<string, object>? Metadata { get; set; }
    }

    public class SendTemplateNotificationRequest
    {
        [Required]
        public string TemplateCode { get; set; } = string.Empty;

        [Required]
        public string Recipient { get; set; } = string.Empty;

        [Required]
        public Dictionary<string, object> Variables { get; set; } = new();

        public Dictionary<string, object>? Metadata { get; set; }
    }

    public class SendBatchNotificationRequest
    {
        [Required]
        public string TemplateCode { get; set; } = string.Empty;

        [Required]
        public List<string> Recipients { get; set; } = new();

        [Required]
        public Dictionary<string, object> Variables { get; set; } = new();
    }

    public class ScheduleNotificationRequest
    {
        [Required]
        public string TemplateCode { get; set; } = string.Empty;

        [Required]
        public string Recipient { get; set; } = string.Empty;

        [Required]
        public Dictionary<string, object> Variables { get; set; } = new();

        [Required]
        public DateTime ScheduledAt { get; set; }
    }

    public class CreateTemplateRequest
    {
        [Required]
        public string Name { get; set; } = string.Empty;

        [Required]
        public string Code { get; set; } = string.Empty;

        [Required]
        public string NotificationType { get; set; } = string.Empty;

        public string? Subject { get; set; }

        [Required]
        public string Content { get; set; } = string.Empty;

        public Dictionary<string, object>? Variables { get; set; }
    }

    public class UpdateTemplateRequest
    {
        public string? Name { get; set; }
        public string? Subject { get; set; }
        public string? Content { get; set; }
        public Dictionary<string, object>? Variables { get; set; }
    }

    public class CreateConfigRequest
    {
        [Required]
        public string NotificationType { get; set; } = string.Empty;

        [Required]
        public string Channel { get; set; } = string.Empty;

        [Required]
        public Dictionary<string, object> Configuration { get; set; } = new();
    }

    public class UpdateConfigRequest
    {
        public bool? IsEnabled { get; set; }
        public Dictionary<string, object>? Configuration { get; set; }
    }
}
